package net.liteheaven.lib;

import com.google.auto.service.AutoService;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;

import net.liteheaven.def.HelloAnnotation;

import java.io.IOException;
import java.util.Collections;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;

@AutoService(Processor.class)
public class HelloProcessor extends AbstractProcessor {

    private Filer filer;
    private Elements elements;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        trace("------------------------------------- HelloProcessor -------------------------------------");
        filer = processingEnv.getFiler(); // for creating file
        elements = processingEnv.getElementUtils(); // 元素辅助类
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (TypeElement element : annotations) {
            if (element.getQualifiedName().toString().equals(HelloAnnotation.class.getCanonicalName())) {
                // main method
                MethodSpec main = MethodSpec.methodBuilder("main")
                        .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                        .returns(void.class)
                        .addParameter(ClassUtil.getContext(), "context")
                        .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")
                        .addStatement("$T view = null", ClassUtil.getView())
                        .addStatement("$T.makeText(context, $S, $L).show()", ClassUtil.getToast(), "注解名：" + element.getSimpleName() + " 被注释对象：" + element.getQualifiedName(), 0)
                        .build();
                // HelloWorld class
                TypeSpec helloWorld = TypeSpec.classBuilder("MainActivity$HelloWorld")
                        .addModifiers(Modifier.PUBLIC)
                        .addMethod(main)
                        .build();

                try {
                    // build com.example.HelloWorld.java
                    JavaFile javaFile = JavaFile.builder("net.liteheaven.testapt", helloWorld)
                            .addFileComment("This codes are generated automatically. Do not modify!")
                            .build();
                    // write to file
                    javaFile.writeTo(filer);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return Collections.singleton(HelloAnnotation.class.getCanonicalName());
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

    private void trace(String text){
        System.out.println(text);
    }
}
